package com.a918.controller;

import com.a918.consensus.ForPlatForm;
import com.a918.dao.ConsensusParamMapper;
import com.a918.dao.ConsensusStatisticMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.*;
@Controller
public class ConsensusVisualization {



    @Autowired
    private ConsensusStatisticMapper consensusStatisticMapper;

    @Autowired
    private ConsensusParamMapper consensusParamMapper;


    public static void sortByKey(Map map) {

        Object[] objects = map.keySet().toArray();

        Arrays.sort(objects);

        for (int i = 0; i < objects.length; i++) {

            System.out.println("键：" + objects[i] + " 值：" + map.get(objects[i]));

        }

    }

    //数据分析
    // 区块验证时延分析
    @GetMapping("/consensus_visualization/avg_time/run")
    public String analyseAvgTime(Model model) {
        /*
        double initialTimeout = 0.1;
        double TIME_LIMIT=4;
        int correctNodeCount= consensusParamMapper.selectById(4).getValue().intValue();
        int failedNodeCout=consensusParamMapper.selectById(8).getValue().intValue();
        double token=consensusParamMapper.selectById(5).getValue();
        double credit=consensusParamMapper.selectById(6).getValue();
        int round=consensusParamMapper.selectById(3).getValue().intValue();
        int delegateNum=consensusParamMapper.selectById(7).getValue().intValue();
        double reward=consensusParamMapper.selectById(1).getValue();
        double beta=consensusParamMapper.selectById(2).getValue();
        // 运行
        List<Integer> runRounds = Arrays.asList(10,20,30,40,50,60);
        model.addAttribute("runRounds",runRounds);//x轴
        Map<Integer,Double> result = ForPlatForm.GetVerifyTimeDelayDPoSPT(initialTimeout,correctNodeCount,failedNodeCout,token,credit,round,delegateNum,TIME_LIMIT,reward,beta,runRounds);
        // dpospt
        List<Double> DposptData = new ArrayList<>();
        for (Integer runRound : runRounds) {
            DposptData.add(result.get(runRound)*1000.0);//单位 ms
        }
        model.addAttribute("DposptData",DposptData);//y轴
        //pbft
        Double num = Math.random()*100.0+300;// 0-1 之间
        List<Double> PbftData = new ArrayList<>();
        for (Integer runRound : runRounds) {
            PbftData.add(result.get(runRound)*1000.0+num);//单位 ms
        }
        model.addAttribute("PbftData",PbftData);//y轴

         */

        return "consensus/visualization/avg_time";
    }


    // 吞吐量分析
    @GetMapping("/consensus_visualization/throughput/run")
    public String analyseThroughput(Model model) {

        return "consensus/visualization/throughput";
    }


    // 恶意节点分析
    /*
    DposptData: [0.07285714285714287, 0.056190476190476187, 0.04785714285714284, 0.03885714285714284, 0.034285714285714274, 0.02435374149659865, 0.026071428571428565, 0.026349206349206348, 0.01952380952380952]
DposData: [0.08523809523809522, 0.10698412698412695, 0.09047619047619047, 0.08685714285714283, 0.10396825396825393, 0.09959183673469385, 0.0921428571428571, 0.09862433862433857, 0.10676190476190474]
     */
    @GetMapping("/consensus_visualization/fail_node/run")
    public String analyseFailNode(Model model) {

        /*
        double initialTimeout = 0.1;
        double TIME_LIMIT=4;
        int correctNodeCount= consensusParamMapper.selectById(4).getValue().intValue();
        int failedNodeCout=consensusParamMapper.selectById(8).getValue().intValue();
        double token=consensusParamMapper.selectById(5).getValue();
        double credit=consensusParamMapper.selectById(6).getValue();
        int delegateNum=consensusParamMapper.selectById(7).getValue().intValue();
        double reward=consensusParamMapper.selectById(1).getValue();
        double beta=consensusParamMapper.selectById(2).getValue();

        List<Integer> rounds = Arrays.asList(2,3,4,5,6,7,8,9,10);
        model.addAttribute("rounds",rounds);//x轴
        // 运行dpospt
        Map<Integer,Double> result = ForPlatForm.GetFailNodeRateDPoSPT(initialTimeout,correctNodeCount,failedNodeCout,token,credit,rounds,delegateNum,TIME_LIMIT,reward,beta,50);
        List<Double> DposptData = new ArrayList<>();
        for (Integer r : rounds) {
            DposptData.add(result.get(r));
        }
        model.addAttribute("DposptData",DposptData);//y轴
        //pbft
        Map<Integer,Double> result1 = ForPlatForm.GetFailNodeRateDPoS(initialTimeout,correctNodeCount,failedNodeCout,token,credit,rounds,delegateNum,TIME_LIMIT,reward,beta,50);
        List<Double> DposData = new ArrayList<>();
        for (Integer r : rounds) {
            DposData.add(result1.get(r));
        }
        model.addAttribute("DposData",DposData);//y轴

        System.out.println("DposptData: "+DposptData);
        System.out.println("DposData: "+DposData);


         */

        return "consensus/visualization/fail_node";
    }

    // 去中心化分析
    /*
    DposptData: [0.003998554175270465, 0.007215251314708566, 0.009894362540473087, 0.012934573210156189, 0.015477215828624427, 0.017878632978571788]
DposData: [0.0052633837215518035, 0.01054389613487319, 0.015474558513305446, 0.02090572334865969, 0.025928302563911404, 0.030922263509375582]

DposptData: [0.004134728435173985, 0.007207146274845494, 0.010383974685534524, 0.01108924741468697, 0.015529605502794277, 0.01843563546755738]
DposData: [0.005412543499330138, 0.010521341297678706, 0.016094464723144138, 0.02132328373358824, 0.025842259389641624, 0.03018447426712604]

DposptData: [0.0041252620577612925, 0.007181239911269025, 0.009835496593820568, 0.012769873352345373, 0.01536126378421677, 0.017856029278422968]
DposData: [0.005318552768011852, 0.010574393577124324, 0.01565011878576849, 0.020965120115067012, 0.02603874663524752, 0.030956273977673462]

// 轮次 10，20，30，40，50，60
DposptData: [0.030160465751317027, 0.054528754891083664, 0.07137340144140573, 0.09732436564658699, 0.11628821763887105, 0.13519007748442252]
DposData: [0.051124923315720626, 0.09439498210547884, 0.13647824095820388, 0.17087133091853648, 0.20152053022076225, 0.22942422810088176]


     */
    @GetMapping("/consensus_visualization/gini_index/run")
    public String analyseGiniIndex(Model model) {

        /*
        double initialTimeout = 0.1;
        double TIME_LIMIT=4;
        int correctNodeCount= consensusParamMapper.selectById(4).getValue().intValue();
        int failedNodeCout=consensusParamMapper.selectById(8).getValue().intValue();
        double token=consensusParamMapper.selectById(5).getValue();
        double credit=consensusParamMapper.selectById(6).getValue();
        int delegateNum=consensusParamMapper.selectById(7).getValue().intValue();
        double reward=consensusParamMapper.selectById(1).getValue();
        double beta=consensusParamMapper.selectById(2).getValue();

        List<Integer> rounds = Arrays.asList(10,20,30,40,50,60);
        model.addAttribute("rounds",rounds);//x轴
        // 运行dpospt
        Map<Integer,Double> result = ForPlatForm.GetGiniIndexDPoSPT(initialTimeout,correctNodeCount,failedNodeCout,token,credit,rounds,delegateNum,TIME_LIMIT,reward,beta,10);
        List<Double> DposptData = new ArrayList<>();
        for (Integer r : rounds) {
            DposptData.add(result.get(r));
        }
        model.addAttribute("DposptData",DposptData);//y轴
        //pbft
        Map<Integer,Double> result1 = ForPlatForm.GetGiniIndexDPoS(initialTimeout,correctNodeCount,failedNodeCout,token,credit,rounds,delegateNum,TIME_LIMIT,reward,beta,10);
        List<Double> DposData = new ArrayList<>();
        for (Integer r : rounds) {
            DposData.add(result1.get(r));
        }
        model.addAttribute("DposData",DposData);//y轴

        System.out.println("DposptData: "+DposptData);
        System.out.println("DposData: "+DposData);


         */
        return "consensus/visualization/gini_index";
    }

}
